package com.usbserial.core;

/**
 * Immutable serial port configuration with a fluent builder.
 */
public final class SerialConfig {

    public static final int PARITY_NONE = 0;
    public static final int PARITY_ODD = 1;
    public static final int PARITY_EVEN = 2;
    public static final int PARITY_MARK = 3;
    public static final int PARITY_SPACE = 4;

    public static final int DATABITS_5 = 5;
    public static final int DATABITS_6 = 6;
    public static final int DATABITS_7 = 7;
    public static final int DATABITS_8 = 8;

    public static final int STOPBITS_1 = 1;
    public static final int STOPBITS_1_5 = 3;
    public static final int STOPBITS_2 = 2;

    public static final int FLOW_CONTROL_OFF = 0;
    public static final int FLOW_CONTROL_RTS_CTS = 1;
    public static final int FLOW_CONTROL_DSR_DTR = 2;
    public static final int FLOW_CONTROL_XON_XOFF = 3;

    final int baudRate;
    final int dataBits;
    final int stopBits;
    final int parity;
    final int flowControl;
    final int readBufferSize;
    final int readTimeoutMillis;
    final int writeTimeoutMillis;

    private SerialConfig(Builder builder) {
        this.baudRate = builder.baudRate;
        this.dataBits = builder.dataBits;
        this.stopBits = builder.stopBits;
        this.parity = builder.parity;
        this.flowControl = builder.flowControl;
        this.readBufferSize = builder.readBufferSize;
        this.readTimeoutMillis = builder.readTimeoutMillis;
        this.writeTimeoutMillis = builder.writeTimeoutMillis;
    }

    public int getBaudRate() {
        return baudRate;
    }

    public int getDataBits() {
        return dataBits;
    }

    public int getStopBits() {
        return stopBits;
    }

    public int getParity() {
        return parity;
    }

    public int getFlowControl() {
        return flowControl;
    }

    public int getReadBufferSize() {
        return readBufferSize;
    }

    public int getReadTimeoutMillis() {
        return readTimeoutMillis;
    }

    public int getWriteTimeoutMillis() {
        return writeTimeoutMillis;
    }

    public static Builder builder() {
        return new Builder();
    }

    public static final class Builder {
        private int baudRate = 115200;
        private int dataBits = DATABITS_8;
        private int stopBits = STOPBITS_1;
        private int parity = PARITY_NONE;
        private int flowControl = FLOW_CONTROL_OFF;
        private int readBufferSize = 1024;
        private int readTimeoutMillis = 1000;
        private int writeTimeoutMillis = 1000;

        private Builder() {
        }

        public Builder baudRate(int value) {
            this.baudRate = value;
            return this;
        }

        public Builder dataBits(int value) {
            this.dataBits = value;
            return this;
        }

        public Builder stopBits(int value) {
            this.stopBits = value;
            return this;
        }

        public Builder parity(int value) {
            this.parity = value;
            return this;
        }

        public Builder flowControl(int value) {
            this.flowControl = value;
            return this;
        }

        public Builder readBufferSize(int value) {
            this.readBufferSize = value;
            return this;
        }

        public Builder readTimeoutMillis(int value) {
            this.readTimeoutMillis = value;
            return this;
        }

        public Builder writeTimeoutMillis(int value) {
            this.writeTimeoutMillis = value;
            return this;
        }

        public SerialConfig build() {
            return new SerialConfig(this);
        }
    }
}
